home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / r_light.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-07  |  21.7 KB  |  1,036 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // r_light.c
  21.  
  22. #include "r_local.h"
  23.  
  24. int    r_dlightframecount;
  25.  
  26. // #define    DLIGHT_CUTOFF    64
  27. #define DLIGHT_CUTOFF    0
  28.  
  29. /*
  30. =============================================================================
  31.  
  32. DYNAMIC LIGHTS BLEND RENDERING
  33.  
  34. =============================================================================
  35. */
  36.  
  37. void R_RenderDlight (dlight_t *light)
  38. {
  39.     int        i, j;
  40.     float    a;
  41.     vec3_t    v;
  42.     float    rad;
  43.  
  44.     rad = light->intensity * 0.35;
  45.  
  46.     VectorSubtract (light->origin, r_origin, v);
  47. #if 0
  48.     // FIXME?
  49.     if (VectorLength (v) < rad)
  50.     {    // view is inside the dlight
  51.         V_AddBlend (light->color[0], light->color[1], light->color[2], light->intensity * 0.0003, v_blend);
  52.         return;
  53.     }
  54. #endif
  55.  
  56.     qglBegin (GL_TRIANGLE_FAN);
  57.     qglColor3f (light->color[0]*0.2, light->color[1]*0.2, light->color[2]*0.2);
  58.     for (i=0 ; i<3 ; i++)
  59.         v[i] = light->origin[i] - vpn[i]*rad;
  60.     qglVertex3fv (v);
  61.     qglColor3f (0,0,0);
  62.     for (i=16 ; i>=0 ; i--)
  63.     {
  64.         a = i/16.0 * M_PI*2;
  65.         for (j=0 ; j<3 ; j++)
  66.             v[j] = light->origin[j] + vright[j]*cos(a)*rad
  67.                 + vup[j]*sin(a)*rad;
  68.         qglVertex3fv (v);
  69.     }
  70.     qglEnd ();
  71. }
  72.  
  73. /*
  74. =============
  75. R_RenderDlights
  76. =============
  77. */
  78. void R_RenderDlights (void)
  79. {
  80.     int        i;
  81.     dlight_t    *l;
  82.  
  83.     if (!gl_flashblend->value)
  84.         return;
  85.  
  86.     r_dlightframecount = r_framecount + 1;    // because the count hasn't
  87.                                             //  advanced yet for this frame
  88.     qglDepthMask (0);
  89.     qglDisable (GL_TEXTURE_2D);
  90.     qglShadeModel (GL_SMOOTH);
  91.     qglEnable (GL_BLEND);
  92.     qglBlendFunc (GL_ONE, GL_ONE);
  93.  
  94.     l = r_newrefdef.dlights;
  95.     for (i=0 ; i<r_newrefdef.num_dlights ; i++, l++)
  96.         R_RenderDlight (l);
  97.  
  98.     qglColor3f (1,1,1);
  99.     qglDisable (GL_BLEND);
  100.     qglEnable (GL_TEXTURE_2D);
  101.     qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  102.     qglDepthMask (1);
  103. }
  104.  
  105.  
  106. /*
  107. =============================================================================
  108.  
  109. DYNAMIC LIGHTS
  110.  
  111. =============================================================================
  112. */
  113.  
  114. /*
  115. =============
  116. R_MarkLights
  117. =============
  118. */
  119. void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
  120. {
  121.     cplane_t    *splitplane;
  122.     float        dist;
  123.     msurface_t    *surf;
  124.     int            i;
  125.     
  126.     if (node->contents != -1)
  127.         return;
  128.  
  129.     splitplane = node->plane;
  130.     dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
  131.     
  132.     if (dist > light->intensity-DLIGHT_CUTOFF)
  133.     {
  134.         R_MarkLights (light, bit, node->children[0]);
  135.         return;
  136.     }
  137.     if (dist < -light->intensity+DLIGHT_CUTOFF)
  138.     {
  139.         R_MarkLights (light, bit, node->children[1]);
  140.         return;
  141.     }
  142.         
  143. // mark the polygons
  144.     surf = r_worldmodel->surfaces + node->firstsurface;
  145.     for (i=0 ; i<node->numsurfaces ; i++, surf++)
  146.     {
  147.         if (surf->dlightframe != r_dlightframecount)
  148.         {
  149.             surf->dlightbits = 0;
  150.             surf->dlightframe = r_dlightframecount;
  151.         }
  152.         surf->dlightbits |= bit;
  153.     }
  154.  
  155.     R_MarkLights (light, bit, node->children[0]);
  156.     R_MarkLights (light, bit, node->children[1]);
  157. }
  158.  
  159.  
  160. /*
  161. =============
  162. R_PushDlights
  163. =============
  164. */
  165. void R_PushDlights (void)
  166. {
  167.     int        i;
  168.     dlight_t    *l;
  169.  
  170.     if (gl_flashblend->value)
  171.         return;
  172.  
  173.     r_dlightframecount = r_framecount + 1;    // because the count hasn't
  174.                                             //  advanced yet for this frame
  175.     l = r_newrefdef.dlights;
  176.     for (i=0 ; i<r_newrefdef.num_dlights ; i++, l++)
  177.         R_MarkLights ( l, 1<<i, r_worldmodel->nodes );
  178. }
  179.  
  180. /*
  181. =============
  182. R_PushDlightsForBModel
  183. =============
  184. */
  185. void R_PushDlightsForBModel (entity_t *e)
  186. {
  187.     int            k;
  188.     dlight_t    *lt;
  189.  
  190.     lt = r_newrefdef.dlights;
  191.     
  192.     if (e->angles[0] || e->angles[1] || e->angles[2])
  193.     {
  194.         vec3_t    temp;
  195.         vec3_t    forward, right, up;
  196.         
  197.         AngleVectors (e->angles, forward, right, up);
  198.         
  199.         for (k=0 ; k<r_newrefdef.num_dlights ; k++, lt++)
  200.         {
  201.             VectorSubtract (lt->origin, e->origin, temp);
  202.             lt->origin[0] = DotProduct (temp, forward);
  203.             lt->origin[1] = -DotProduct (temp, right);
  204.             lt->origin[2] = DotProduct (temp, up);
  205.             R_MarkLights (lt, 1<<k, e->model->nodes + e->model->firstnode);
  206.             VectorAdd (temp, e->origin, lt->origin);
  207.         }
  208.     } 
  209.     else
  210.     {
  211.         for (k=0 ; k<r_newrefdef.num_dlights ; k++, lt++)
  212.         {
  213.             VectorSubtract (lt->origin, e->origin, lt->origin);
  214.             R_MarkLights (lt, 1<<k, e->model->nodes + e->model->firstnode);
  215.             VectorAdd (lt->origin, e->origin, lt->origin);
  216.         }
  217.     }
  218. }
  219.  
  220. /*
  221. =============================================================================
  222.  
  223. LIGHT SAMPLING
  224.  
  225. =============================================================================
  226. */
  227.  
  228. vec3_t            pointcolor;
  229. cplane_t        *lightplane;        // used as shadow plane
  230. vec3_t            lightspot;
  231.  
  232. int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
  233. {
  234.     float        front, back, frac;
  235.     int            side;
  236.     cplane_t    *plane;
  237.     vec3_t        mid;
  238.     msurface_t    *surf;
  239.     int            s, t, ds, dt;
  240.     int            i;
  241.     mtexinfo_t    *tex;
  242.     byte        *lightmap;
  243.     int            maps;
  244.     int            r;
  245.     vec3_t        scale;
  246.  
  247.     if (node->contents != -1)
  248.         return -1;        // didn't hit anything
  249.     
  250. // calculate mid point
  251.  
  252. // FIXME: optimize for axial
  253.     plane = node->plane;
  254.     front = DotProduct (start, plane->normal) - plane->dist;
  255.     back = DotProduct (end, plane->normal) - plane->dist;
  256.     side = front < 0;
  257.     
  258.     if ( (back < 0) == side)
  259.         return RecursiveLightPoint (node->children[side], start, end);
  260.     
  261.     frac = front / (front-back);
  262.     mid[0] = start[0] + (end[0] - start[0])*frac;
  263.     mid[1] = start[1] + (end[1] - start[1])*frac;
  264.     mid[2] = start[2] + (end[2] - start[2])*frac;
  265.     
  266. // go down front side    
  267.     r = RecursiveLightPoint (node->children[side], start, mid);
  268.     if (r >= 0)
  269.         return r;        // hit something
  270.         
  271.     if ( (back < 0) == side )
  272.         return -1;        // didn't hit anuthing
  273.         
  274. // check for impact on this node
  275.     VectorCopy (mid, lightspot);
  276.     lightplane = plane;
  277.  
  278.     surf = r_worldmodel->surfaces + node->firstsurface;
  279.     for (i=0 ; i<node->numsurfaces ; i++, surf++)
  280.     {
  281.         tex = surf->texinfo;
  282.  
  283.         if (tex->flags & (SURF_WARP|SURF_SKY)) 
  284.             continue;    // no lightmaps
  285.  
  286.         s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
  287.         if (s < surf->texturemins[0])
  288.             continue;
  289.  
  290.         t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];
  291.         if (t < surf->texturemins[1])
  292.             continue;
  293.         
  294.         ds = s - surf->texturemins[0];
  295.         dt = t - surf->texturemins[1];
  296.         
  297.         if ( ds > surf->extents[0] || dt > surf->extents[1] )
  298.             continue;
  299.  
  300.         lightmap = surf->samples;
  301.         if (!surf->samples)
  302.             return 0;
  303.  
  304.         ds >>= 4;
  305.         dt >>= 4;
  306.  
  307.         VectorClear (pointcolor);
  308.  
  309.         lightmap += 3*(dt * ((surf->extents[0]>>4)+1) + ds);
  310.         
  311.         for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;    maps++)
  312.         {
  313.             for (i=0 ; i<3 ; i++)
  314.                 scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
  315.             
  316.             pointcolor[0] += lightmap[0] * scale[0] * (1.0/255);
  317.             pointcolor[1] += lightmap[1] * scale[1] * (1.0/255);
  318.             pointcolor[2] += lightmap[2] * scale[2] * (1.0/255);
  319.             lightmap += 3*((surf->extents[0]>>4)+1) *
  320.                 ((surf->extents[1]>>4)+1);
  321.         }
  322.         
  323.         return 1;
  324.     }
  325.  
  326. // go down back side
  327.     return RecursiveLightPoint (node->children[!side], mid, end);
  328. }
  329.  
  330. /*
  331. ===============
  332. R_LightPoint
  333. ===============
  334. */
  335. void R_LightPoint (vec3_t p, vec3_t color)
  336. {
  337.     vec3_t        end;
  338.     float        r;
  339.     int            lnum;
  340.     dlight_t    *dl;
  341.     float        light;
  342.     vec3_t        dist, dlightcolor;
  343.     float        add;
  344.     
  345.     if (!r_worldmodel->lightdata)
  346.     {
  347.         color[0] = color[1] = color[2] = 1.0;
  348.         return;
  349.     }
  350.     
  351.     end[0] = p[0];
  352.     end[1] = p[1];
  353.     end[2] = p[2] - 2048;
  354.     
  355.     r = RecursiveLightPoint (r_worldmodel->nodes, p, end);
  356.     
  357.     if (r == -1)
  358.     {
  359.         VectorCopy (vec3_origin, color);
  360.     }
  361.     else
  362.     {
  363.         VectorCopy (pointcolor, color);
  364.     }
  365.  
  366.     //
  367.     // add dynamic lights
  368.     //
  369.     light = 0;
  370.     dl = r_newrefdef.dlights;
  371.     VectorClear ( dlightcolor );
  372.     for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++, dl++)
  373.     {
  374.         VectorSubtract (currententity->origin,
  375.                         dl->origin,
  376.                         dist);
  377.         add = dl->intensity - VectorLength(dist);
  378.         if (add > 0)
  379.         {
  380.             add *= (1.0/256);
  381.             VectorMA (dlightcolor, add, dl->color, dlightcolor);
  382.         }
  383.     }
  384.  
  385.     VectorMA (color, gl_modulate->value, dlightcolor, color);
  386. }
  387.  
  388.  
  389. //===================================================================
  390.  
  391. /*
  392. =============
  393. R_AddStainMap
  394. =============
  395. */
  396. void R_AddStainMap (stain_t *st, msurface_t *surf)
  397. {
  398.     int            i;
  399.     mtexinfo_t    *tex;
  400.     int            sd, td;
  401.     float        fsacc, ftacc;
  402.     float        dist, fdist, frad, fminlight;
  403.     vec3_t        impact, local;
  404.     int            s, t, smax, tmax;
  405.     byte        *pfBL;
  406.     
  407.     if (!surf->stainsamples)
  408.         return;
  409.     tex = surf->texinfo;
  410.     if ( (tex->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP) ) )
  411.         return;
  412.     
  413.     if ( surf->plane->type < 3 ) {
  414.         dist = st->origin[surf->plane->type] - surf->plane->dist;
  415.     } else {
  416.         dist = DotProduct (st->origin, surf->plane->normal) - surf->plane->dist;
  417.     }
  418.     
  419.     if (surf->flags & SURF_PLANEBACK)
  420.         fdist = -dist;
  421.     else
  422.         fdist = dist;
  423.     
  424.     frad = st->intensity - fabs (fdist);
  425.     if (frad < 0)
  426.         return;
  427.     
  428.     smax = (surf->extents[0]>>4)+1;
  429.     tmax = (surf->extents[1]>>4)+1;
  430.     
  431.     fminlight = frad;
  432.     
  433.     for (i = 0 ; i<3 ; i++)
  434.         impact[i] = st->origin[i] - surf->plane->normal[i] * fdist;
  435.     
  436.     local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3] - surf->texturemins[0];
  437.     local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3] - surf->texturemins[1];
  438.     
  439.     pfBL = surf->stainsamples;
  440.     surf->cached_light[0] = 0;
  441.     
  442.     for (t = 0, ftacc = 0 ; t<tmax ; t++, ftacc += 16)
  443.     {
  444.         td = local[1] - ftacc;
  445.         if ( td < 0 )
  446.             td = -td;
  447.         for ( s=0, fsacc = 0 ; s<smax ; s++, fsacc += 16, pfBL += 3)
  448.         {
  449.             sd = Q_ftol( local[0] - fsacc );
  450.             
  451.             if ( sd < 0 )
  452.                 sd = -sd;
  453.             
  454.             if (sd > td)
  455.                 fdist = sd + (td>>1);
  456.             else
  457.                 fdist = td + (sd>>1);
  458.             
  459.             if ( fdist < fminlight ) 
  460.             {
  461.                 float alpha, mult;
  462.                 int test;
  463.                 
  464.                 mult = frad / fdist;
  465.                 if (mult > 5.0) 
  466.                     mult = 5.0;
  467.                 
  468.                 alpha = st->alpha * mult;
  469.                 if (alpha > 255) 
  470.                     alpha = 255;
  471.                 if (alpha > st->alpha) 
  472.                     alpha = st->alpha;
  473.                 if (alpha < 0) 
  474.                     alpha = 0;
  475.                 alpha *= (1.0 / 255.0);
  476.                 
  477.                 for (i=0;i<3;i++) 
  478.                 {
  479.                     test = Q_ftol( (1-alpha) * (float)pfBL[i] + alpha * st->color[i] );
  480.                     
  481.                     if (test > 255)
  482.                         pfBL[i] = 255;
  483.                     else if (test < 0)
  484.                         pfBL[i] = 0;
  485.                     else
  486.                         pfBL[i] = (byte)(test);
  487.                 }
  488.             }
  489.         }
  490.     }
  491. }
  492.  
  493. /*
  494. =============
  495. R_StainNode
  496. =============
  497. */
  498. void R_StainNode (stain_t *st, mnode_t *node)
  499. {
  500.     int        c;
  501.     float    dist;
  502.     msurface_t *surf;
  503.     
  504.     if (node->contents != -1)
  505.         return;
  506.  
  507.     if ( node->plane->type < 3 ) {
  508.         dist = st->origin[node->plane->type] - node->plane->dist;
  509.     } else {
  510.         dist = DotProduct (st->origin, node->plane->normal) - node->plane->dist;
  511.     }
  512.  
  513.     if (dist > st->intensity)
  514.     {
  515.         R_StainNode (st, node->children[0]);
  516.         return;
  517.     }
  518.  
  519.     if (dist < -st->intensity)
  520.     {
  521.         R_StainNode (st, node->children[1]);
  522.         return;
  523.     }
  524.  
  525.     for (c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) 
  526.     {
  527.         R_AddStainMap ( st, surf );
  528.     }
  529.  
  530.     if (node->contents == -1)
  531.         R_StainNode (st, node->children[0]);
  532.     if (node->contents == -1)
  533.         R_StainNode (st, node->children[1]);
  534. }
  535.  
  536. /*
  537. =============
  538. R_PushStains
  539. =============
  540. */
  541. void R_PushStains (void)
  542. {
  543.     int        i;
  544.     stain_t    *st;
  545.  
  546.     st = r_newrefdef.stains;
  547.     for (i=0 ; i<r_newrefdef.num_stains ; i++, st++) {
  548.         R_StainNode ( st, r_worldmodel->nodes );
  549.     }
  550. }
  551.  
  552. /*
  553. =============
  554. R_PushStainsForBModel
  555. =============
  556. */
  557. void R_PushStainsForBModel (entity_t *e)
  558. {
  559.     int i, c;
  560.     stain_t    *st;
  561.     model_t *model;
  562.     msurface_t *surf;
  563.  
  564.     st = r_newrefdef.stains;
  565.     model = e->model;
  566.     
  567.     if (e->angles[0] || e->angles[1] || e->angles[2])
  568.     {
  569.         vec3_t temp;
  570.         vec3_t forward, right, up;
  571.  
  572.         AngleVectors ( e->angles, forward, right, up );
  573.         
  574.         for (i=0 ; i<r_newrefdef.num_stains ; i++, st++) {
  575.             VectorSubtract (st->origin, e->origin, temp);
  576.             st->origin[0] = DotProduct (temp, forward);
  577.             st->origin[1] = -DotProduct (temp, right);
  578.             st->origin[2] = DotProduct (temp, up);
  579.  
  580.             surf = &model->surfaces[model->firstmodelsurface];
  581.             for (c=0 ; c<model->nummodelsurfaces ; c++, surf++)
  582.             {
  583.                 R_AddStainMap ( st, surf );
  584.             }
  585.  
  586.             VectorAdd ( temp, e->origin, st->origin );
  587.         }
  588.     }
  589.     else
  590.     {
  591.         for (i=0 ; i<r_newrefdef.num_stains ; i++, st++) {
  592.             VectorSubtract (st->origin, e->origin, st->origin);
  593.  
  594.             surf = &model->surfaces[model->firstmodelsurface];
  595.             for (c=0 ; c<model->nummodelsurfaces ; c++, surf++)
  596.             {
  597.                 R_AddStainMap ( st, surf );
  598.             }
  599.  
  600.             VectorAdd ( st->origin, e->origin, st->origin );
  601.         }
  602.     }
  603. }
  604.  
  605. //===================================================================
  606.  
  607. static float s_blocklights[34*34*3];
  608.  
  609. /*
  610. ===============
  611. R_AddStainMaps
  612. ===============
  613. */
  614. void R_AddStainMaps (msurface_t *surf)
  615. {
  616.     int            s, t, i;
  617.     int            smax, tmax;
  618.     float        *pfBL;
  619.     byte        *pfBS;
  620.     float        scale;
  621.  
  622.     scale = gl_modulate->value;
  623.  
  624.     smax = (surf->extents[0]>>4)+1;
  625.     tmax = (surf->extents[1]>>4)+1;
  626.  
  627.     pfBL = s_blocklights;
  628.     pfBS = surf->stainsamples;
  629.  
  630.     for (t = 0; t<tmax; t++)
  631.         for ( s=0; s<smax; s++, pfBL += 3, pfBS +=3)
  632.             for (i=0;i<3;i++)
  633.             {
  634.                 if (pfBL[i] > pfBS[i]*scale)
  635.                     pfBL[i] = pfBS[i]*scale;
  636.             }
  637. }
  638.  
  639. /*
  640. ===============
  641. R_AddDynamicLights
  642. ===============
  643. */
  644. void R_AddDynamicLights (msurface_t *surf)
  645. {
  646.     int            lnum;
  647.     int            sd, td;
  648.     float        fdist, frad, fminlight;
  649.     vec3_t        impact, local, dlorigin;
  650.     int            s, t;
  651.     int            i;
  652.     int            smax, tmax;
  653.     mtexinfo_t    *tex;
  654.     dlight_t    *dl;
  655.     float        *pfBL;
  656.     float        fsacc, ftacc;
  657.     qboolean    rotated = false;
  658.     vec3_t        temp;
  659.     vec3_t        forward, right, up;
  660.  
  661.     smax = (surf->extents[0]>>4)+1;
  662.     tmax = (surf->extents[1]>>4)+1;
  663.     tex = surf->texinfo;
  664.  
  665.     if (currententity->angles[0] || currententity->angles[1] || currententity->angles[2])
  666.     {
  667.         rotated = true;
  668.         AngleVectors (currententity->angles, forward, right, up);
  669.     }
  670.  
  671.     dl = r_newrefdef.dlights;
  672.     for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++, dl++)
  673.     {
  674.         if ( !(surf->dlightbits & (1<<lnum) ) )
  675.             continue;        // not lit by this light
  676.  
  677.         frad = dl->intensity;
  678.         VectorCopy ( dl->origin, dlorigin );
  679.  
  680.         VectorSubtract (dlorigin, currententity->origin, dlorigin);
  681.         if (rotated)
  682.         {
  683.             VectorCopy (dlorigin, temp);
  684.             dlorigin[0] = DotProduct (temp, forward);
  685.             dlorigin[1] = -DotProduct (temp, right);
  686.             dlorigin[2] = DotProduct (temp, up);
  687.         }
  688.  
  689.         fdist = DotProduct (dlorigin, surf->plane->normal) - surf->plane->dist;
  690.         frad -= fabs(fdist);
  691.         // rad is now the highest intensity on the plane
  692.  
  693.         fminlight = DLIGHT_CUTOFF;    // FIXME: make configurable?
  694.         if (frad < fminlight)
  695.             continue;
  696.         fminlight = frad - fminlight;
  697.  
  698.         for (i=0 ; i<3 ; i++)
  699.         {
  700.             impact[i] = dlorigin[i] -
  701.                     surf->plane->normal[i]*fdist;
  702.         }
  703.  
  704.         local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3] - surf->texturemins[0];
  705.         local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3] - surf->texturemins[1];
  706.  
  707.         pfBL = s_blocklights;
  708.         for (t = 0, ftacc = 0 ; t<tmax ; t++, ftacc += 16)
  709.         {
  710.             td = local[1] - ftacc;
  711.             if ( td < 0 )
  712.                 td = -td;
  713.  
  714.             for ( s=0, fsacc = 0 ; s<smax ; s++, fsacc += 16, pfBL += 3)
  715.             {
  716.                 sd = Q_ftol( local[0] - fsacc );
  717.  
  718.                 if ( sd < 0 )
  719.                     sd = -sd;
  720.  
  721.                 if (sd > td)
  722.                     fdist = sd + (td>>1);
  723.                 else
  724.                     fdist = td + (sd>>1);
  725.  
  726.                 if ( fdist < fminlight )
  727.                 {
  728.                     pfBL[0] += ( fminlight - fdist ) * dl->color[0];
  729.                     pfBL[1] += ( fminlight - fdist ) * dl->color[1];
  730.                     pfBL[2] += ( fminlight - fdist ) * dl->color[2];
  731.                 }
  732.             }
  733.         }
  734.     }
  735. }
  736.  
  737.  
  738. /*
  739. ** R_SetCacheState
  740. */
  741. void R_SetCacheState( msurface_t *surf )
  742. {
  743.     int maps;
  744.  
  745.     for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  746.          maps++)
  747.     {
  748.         surf->cached_light[maps] = r_newrefdef.lightstyles[surf->styles[maps]].white;
  749.     }
  750. }
  751.  
  752. /*
  753. ===============
  754. R_BuildLightMap
  755.  
  756. Combine and scale multiple lightmaps into the floating format in blocklights
  757. ===============
  758. */
  759. void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
  760. {
  761.     int            smax, tmax;
  762.     int            r, g, b, a, max;
  763.     int            i, j, size;
  764.     byte        *lightmap;
  765.     float        scale[4];
  766.     int            nummaps;
  767.     float        *bl;
  768.     lightstyle_t    *style;
  769.     int monolightmap;
  770.  
  771.     if ( SurfaceHasNoLightmap( surf ) )
  772.         Com_Error (ERR_DROP, "R_BuildLightMap called for non-lit surface");
  773.  
  774.     smax = (surf->extents[0]>>4)+1;
  775.     tmax = (surf->extents[1]>>4)+1;
  776.     size = smax*tmax;
  777.     if (size > (sizeof(s_blocklights)>>4) )
  778.         Com_Error (ERR_DROP, "Bad s_blocklights size");
  779.  
  780. // set to full bright if no light data
  781.     if (!surf->samples)
  782.     {
  783.         int maps;
  784.  
  785.         for (i=0 ; i<size*3 ; i++)
  786.             s_blocklights[i] = 255;
  787.         for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  788.              maps++)
  789.         {
  790.             style = &r_newrefdef.lightstyles[surf->styles[maps]];
  791.         }
  792.         goto store;
  793.     }
  794.  
  795.     // count the # of maps
  796.     for ( nummaps = 0 ; nummaps < MAXLIGHTMAPS && surf->styles[nummaps] != 255 ;
  797.          nummaps++)
  798.         ;
  799.  
  800.     lightmap = surf->samples;
  801.  
  802.     // add all the lightmaps
  803.     if ( nummaps == 1 )
  804.     {
  805.         int maps;
  806.  
  807.         for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  808.              maps++)
  809.         {
  810.             bl = s_blocklights;
  811.  
  812.             for (i=0 ; i<3 ; i++)
  813.                 scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
  814.  
  815.             if ( scale[0] == 1.0F &&
  816.                  scale[1] == 1.0F &&
  817.                  scale[2] == 1.0F )
  818.             {
  819.                 for (i=0 ; i<size ; i++, bl+=3)
  820.                 {
  821.                     bl[0] = lightmap[i*3+0];
  822.                     bl[1] = lightmap[i*3+1];
  823.                     bl[2] = lightmap[i*3+2];
  824.                 }
  825.             }
  826.             else
  827.             {
  828.                 for (i=0 ; i<size ; i++, bl+=3)
  829.                 {
  830.                     bl[0] = lightmap[i*3+0] * scale[0];
  831.                     bl[1] = lightmap[i*3+1] * scale[1];
  832.                     bl[2] = lightmap[i*3+2] * scale[2];
  833.                 }
  834.             }
  835.             lightmap += size*3;        // skip to next lightmap
  836.         }
  837.     }
  838.     else
  839.     {
  840.         int maps;
  841.  
  842.         memset( s_blocklights, 0, sizeof( s_blocklights[0] ) * size * 3 );
  843.  
  844.         for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  845.              maps++)
  846.         {
  847.             bl = s_blocklights;
  848.  
  849.             for (i=0 ; i<3 ; i++)
  850.                 scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
  851.  
  852.             if ( scale[0] == 1.0F &&
  853.                  scale[1] == 1.0F &&
  854.                  scale[2] == 1.0F )
  855.             {
  856.                 for (i=0 ; i<size ; i++, bl+=3 )
  857.                 {
  858.                     bl[0] += lightmap[i*3+0];
  859.                     bl[1] += lightmap[i*3+1];
  860.                     bl[2] += lightmap[i*3+2];
  861.                 }
  862.             }
  863.             else
  864.             {
  865.                 for (i=0 ; i<size ; i++, bl+=3)
  866.                 {
  867.                     bl[0] += lightmap[i*3+0] * scale[0];
  868.                     bl[1] += lightmap[i*3+1] * scale[1];
  869.                     bl[2] += lightmap[i*3+2] * scale[2];
  870.                 }
  871.             }
  872.             lightmap += size*3;        // skip to next lightmap
  873.         }
  874.     }
  875.  
  876. // add all the dynamic lights
  877.     if (surf->dlightframe == r_framecount)
  878.         R_AddDynamicLights (surf);
  879.  
  880.     if (surf->stainsamples)
  881.         R_AddStainMaps (surf);
  882.  
  883. // put into texture format
  884. store:
  885.     stride -= (smax<<2);
  886.     bl = s_blocklights;
  887.  
  888.     monolightmap = gl_monolightmap->string[0];
  889.  
  890.     if ( monolightmap == '0' )
  891.     {
  892.         for (i=0 ; i<tmax ; i++, dest += stride)
  893.         {
  894.             for (j=0 ; j<smax ; j++)
  895.             {
  896.                 r = Q_ftol( bl[0] );
  897.                 g = Q_ftol( bl[1] );
  898.                 b = Q_ftol( bl[2] );
  899.  
  900.                 // catch negative lights
  901.                 if (r < 0)
  902.                     r = 0;
  903.                 if (g < 0)
  904.                     g = 0;
  905.                 if (b < 0)
  906.                     b = 0;
  907.  
  908.                 /*
  909.                 ** determine the brightest of the three color components
  910.                 */
  911.                 if (r > g)
  912.                     max = r;
  913.                 else
  914.                     max = g;
  915.                 if (b > max)
  916.                     max = b;
  917.  
  918.                 /*
  919.                 ** alpha is ONLY used for the mono lightmap case.  For this reason
  920.                 ** we set it to the brightest of the color components so that 
  921.                 ** things don't get too dim.
  922.                 */
  923.                 a = max;
  924.  
  925.                 /*
  926.                 ** rescale all the color components if the intensity of the greatest
  927.                 ** channel exceeds 1.0
  928.                 */
  929.                 if (max > 255)
  930.                 {
  931.                     float t = 255.0F / max;
  932.  
  933.                     r = r*t;
  934.                     g = g*t;
  935.                     b = b*t;
  936.                     a = a*t;
  937.                 }
  938.  
  939.                 dest[0] = r;
  940.                 dest[1] = g;
  941.                 dest[2] = b;
  942.                 dest[3] = a;
  943.  
  944.                 bl += 3;
  945.                 dest += 4;
  946.             }
  947.         }
  948.     }
  949.     else
  950.     {
  951.         for (i=0 ; i<tmax ; i++, dest += stride)
  952.         {
  953.             for (j=0 ; j<smax ; j++)
  954.             {
  955.                 
  956.                 r = Q_ftol( bl[0] );
  957.                 g = Q_ftol( bl[1] );
  958.                 b = Q_ftol( bl[2] );
  959.  
  960.                 // catch negative lights
  961.                 if (r < 0)
  962.                     r = 0;
  963.                 if (g < 0)
  964.                     g = 0;
  965.                 if (b < 0)
  966.                     b = 0;
  967.  
  968.                 /*
  969.                 ** determine the brightest of the three color components
  970.                 */
  971.                 if (r > g)
  972.                     max = r;
  973.                 else
  974.                     max = g;
  975.                 if (b > max)
  976.                     max = b;
  977.  
  978.                 /*
  979.                 ** alpha is ONLY used for the mono lightmap case.  For this reason
  980.                 ** we set it to the brightest of the color components so that 
  981.                 ** things don't get too dim.
  982.                 */
  983.                 a = max;
  984.  
  985.                 /*
  986.                 ** rescale all the color components if the intensity of the greatest
  987.                 ** channel exceeds 1.0
  988.                 */
  989.                 if (max > 255)
  990.                 {
  991.                     float t = 255.0F / max;
  992.  
  993.                     r = r*t;
  994.                     g = g*t;
  995.                     b = b*t;
  996.                     a = a*t;
  997.                 }
  998.  
  999.                 /*
  1000.                 ** So if we are doing alpha lightmaps we need to set the R, G, and B
  1001.                 ** components to 0 and we need to set alpha to 1-alpha.
  1002.                 */
  1003.                 switch ( monolightmap )
  1004.                 {
  1005.                 case 'L':
  1006.                 case 'I':
  1007.                     r = a;
  1008.                     g = b = 0;
  1009.                     break;
  1010.                 case 'C':
  1011.                     // try faking colored lighting
  1012.                     a = 255 - ((r+g+b)/3);
  1013.                     r *= a/255.0;
  1014.                     g *= a/255.0;
  1015.                     b *= a/255.0;
  1016.                     break;
  1017.                 case 'A':
  1018.                 default:
  1019.                     r = g = b = 0;
  1020.                     a = 255 - a;
  1021.                     break;
  1022.                 }
  1023.  
  1024.                 dest[0] = r;
  1025.                 dest[1] = g;
  1026.                 dest[2] = b;
  1027.                 dest[3] = a;
  1028.  
  1029.                 bl += 3;
  1030.                 dest += 4;
  1031.             }
  1032.         }
  1033.     }
  1034. }
  1035.  
  1036.